/**
 * 
 */
package com.android.whereismy;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import android.app.ProgressDialog;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.android.whereismy.mail.MailControler;
import com.android.whereismy.util.CmnConsts;
import com.android.whereismy.util.CmnUtils;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.MapView.LayoutParams;

/**
 * @author akarae
 *
 */
public class Controller extends MapActivity {

    MapView mapView;
    MapController mapControl;
    LocationManager controllerLocationMgr;
    LocationManager unitLocationMgr;
    Criteria criteria;
    Location controllerLocation;
    Location unitLocation;
    Address unitAddress;
    GeoPoint controllerGeoPoint;
    GeoPoint unitGeoPoint;
    UnitLocationOverlay unitLocationOverlay;
    
    int intLatController;
    int intLatUnit;
    
    int intLongController;
    int intLongUnit;
    
    Date rptDate;
    String provider;
    
    String strUnitId;
    String strAuthKey;
    
    boolean clickSubmit;
    
    ImageView unitMarker;
    ImageView controllerMarker;
    
    private ProgressDialog pd;
    Boolean mailFlg = false;
    Map <String, Object> resultMap = new HashMap <String, Object>();
    
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.controller);
        
        clickSubmit = false;
        
        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        mapView.setSatellite(false);
        
        mapControl = mapView.getController();
        mapControl.setZoom(17);
        
        unitMarker = new ImageView(getApplicationContext());
        controllerMarker = new ImageView(getApplicationContext());
        
        // set-up LocationManager
        setUpLocation();

        // get current location
        getCurrentLocation();
        
        // set controllerMarger
        setControllerMarker();
        
        // animate to location
        moveOn(controllerGeoPoint);
        
        // submit button
        final Button button_seek = (Button) findViewById(R.id.button_seek);
        button_seek.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            
                clickSubmit = true;
            	
                EditText textUnitId = (EditText) findViewById(R.id.EditUnitId);
                EditText textAuthKey = (EditText) findViewById(R.id.EditAuthKey);
            
                strUnitId = textUnitId.getText().toString();
                strAuthKey = CmnUtils.getMd5Hash(textAuthKey.getText().toString());
            
                if (CmnUtils.isStrEmpty(strUnitId)) {
                    Toast.makeText(Controller.this, "input UnitID", Toast.LENGTH_LONG).show();
                    return;
                }
                
                getReport();
            }
        });
        
        // clear button
        final Button button_clear = (Button) findViewById(R.id.button_clear);
        button_clear.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                EditText textUnitId = (EditText) findViewById(R.id.EditUnitId);
                EditText textAuthKey = (EditText) findViewById(R.id.EditAuthKey);
                
                // reset EditText to null
                textUnitId.setText(null);
                textAuthKey.setText(null);
            }
        });

        // current_location button
        final Button button_cur_location = (Button) findViewById(R.id.button_my_location);
        button_cur_location.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                getCurrentLocation();
                setControllerMarker();
                moveOn(controllerGeoPoint);
            }
        });
        
        // unit button
        final Button button_unit_location = (Button) findViewById(R.id.button_unit_location);
        button_unit_location.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

            if (!clickSubmit) {
                return;
            }
                moveOn(unitGeoPoint);
            }
        });
    }
    
    @Override
    public void onStart() {
        super.onStart();
    }
    
    /**
     * set-up related to LBS
     */
    public void setUpLocation() {
        controllerLocationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        criteria = new Criteria();
        criteria.setAccuracy(Criteria.NO_REQUIREMENT);
        criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
    }
    
    /**
     * get current location(by best provider)
     */
    public void getCurrentLocation() {
        String bestProvider = controllerLocationMgr.getBestProvider(criteria, true);
        controllerLocationMgr.requestLocationUpdates(bestProvider, 5000, 1, locationListener);
        controllerLocation = controllerLocationMgr.getLastKnownLocation(bestProvider);
        // unitLocation copy
        unitLocation = controllerLocation;
        intLatController = (int) (controllerLocation.getLatitude() * 1E6);
        intLongController = (int) (controllerLocation.getLongitude() * 1E6);
        controllerGeoPoint = new GeoPoint(intLatController, intLongController);
    }

    /**
     * get a known address from latitude and longitude.
     */
    protected void getGeocode() {
        Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
        List <Address> addrList = null;
        try {
            addrList = geocoder.getFromLocation(
                    unitLocation.getLatitude(), 
                    unitLocation.getLongitude(), 
                    CmnConsts.MAX_RESULT);
        } catch (Throwable t) {
            Log.d(CmnConsts.DEBUG_TAG, "Geocode failed");
        }
        if (addrList.size() > 0) {
            unitAddress = addrList.get(0);
        }
    }
    
    protected void setOverlay() {
        // Add the MyPositionOverlay
        unitLocationOverlay = new UnitLocationOverlay(unitLocation, unitAddress, rptDate, provider);
        List<Overlay> overlays = mapView.getOverlays();
        overlays.clear();
        overlays.add(0, unitLocationOverlay);
    }
    
    protected void setUnitMarker() {
        LayoutParams mapMarkerParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, 
                LayoutParams.WRAP_CONTENT, 
                unitGeoPoint, 
                LayoutParams.CENTER);
        
        
        unitMarker.setImageResource(R.drawable.unit);
        mapView.removeView(unitMarker);
        mapView.addView(unitMarker, mapMarkerParams);
    }
    
    protected void setControllerMarker() {
        LayoutParams mapMarkerParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, 
                LayoutParams.WRAP_CONTENT, 
                controllerGeoPoint, 
                LayoutParams.CENTER);
        
        
        controllerMarker.setImageResource(R.drawable.controller);
        mapView.removeView(controllerMarker);
        mapView.addView(controllerMarker, mapMarkerParams);
    }
    
    /**
     * move the map to indicated location.
     */
    public void moveOn(GeoPoint targetGeoPoint) {
        mapControl.animateTo(targetGeoPoint);
        mapControl.setCenter(targetGeoPoint);
    }
    
    public void getReport() {
        pd = ProgressDialog.show(this, CmnConsts.PRC_TITLE, CmnConsts.PRC_SEEK, true, false);
        Thread thread = new Thread(new Runnable() {
                  public void run() {
                      
                      MailControler mc = new MailControler(getResources());
                      try {
                          // receive a mail
                          resultMap = mc.receiveMail(
                                  strUnitId, 
                                  strAuthKey);
                      } catch (Exception e) {
                          Log.d(CmnConsts.DEBUG_TAG, "receive failed");
                          mailFlg = false;
                      }
                      mailFlg = true;
                      handler.sendEmptyMessage(0);
                      //위젯이나 뷰를 생성하거나 작업하지 못한다. 
                  }
        });
        thread.start();
    }

    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            pd.dismiss();
            if (!mailFlg) {
                Toast.makeText(Controller.this, "receive failed", Toast.LENGTH_LONG).show();
            } else {
                intLatUnit = (Integer) resultMap.get(CmnConsts.LAT);
                intLongUnit = (Integer) resultMap.get(CmnConsts.LONG);
                rptDate = (Date) resultMap.get(CmnConsts.RPT_TIME);
                provider = (String) resultMap.get(CmnConsts.PROVIDER);
                unitGeoPoint = new GeoPoint(intLatUnit, intLongUnit);
                unitLocation.setLatitude(intLatUnit / 1E6);
                unitLocation.setLongitude(intLongUnit / 1E6);
                getGeocode();
                setUnitMarker();
                setOverlay();
                moveOn(unitGeoPoint);
            }
        }
    };
    
    private final LocationListener locationListener = new LocationListener() {
        // when location updated
        public void onLocationChanged(Location location) {
            controllerLocation = location;
        }
        
        public void onProviderDisabled(String provider) {
            // TODO when provider will be changed to Disabled
            
        }
        
        public void onProviderEnabled(String provider) {
            // TODO when provider will be changed to Enabled
            
        }
        
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO when provider status will be changed
        }
    };
}
